package com.ruoyi.tester.executor.thread;

import java.util.concurrent.AbstractExecutorService;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @author SongJun
 * @description
 * InvolutedThreadPool改进了ThreadPoolExecutor的调度策略,
 * 增加了一个参数startExtraThreadQueueSize表示队列中累积的任务数超过这个值之后就会直接开启新线程处理任务,
 * 避免ThreadPoolExecutor中的逻辑"队列任务堆积满之后才会开启新线程进行处理",
 * 当队列满时,如果刚好有一批较多的任务到达,即使开启最大处理线程数仍不足以吞下这一批任务, 那么就会触发拒绝策略.
 * 而新的逻辑可以指定队列装满之前, 提前开启新线程帮助处理任务, 最大化地利用队列带来的任务堆积能力.
 * @date 2022/3/16 16:37
 */
public class ThreadTest {
    public static void main(String[] args) throws InterruptedException {
//        test1();
//        test2();
        test3();
//        test4();
    }
    //普通线程池匀速运行
    public static void test1() throws InterruptedException {
        ThreadPoolExecutor pool = new ThreadPoolExecutor(2, 4, 3, TimeUnit.SECONDS, new ArrayBlockingQueue<>(20));
        pool.allowCoreThreadTimeOut(true);
        runWithUniformSpeed(pool);
    }
    //卷池匀速运行
    public static void test2() throws InterruptedException {
        InvolutedThreadPool pool = new InvolutedThreadPool(2, 4, 3, TimeUnit.SECONDS, new ArrayBlockingQueue<>(20), 10);
        pool.allowCoreThreadTimeOut(true);
        runWithUniformSpeed(pool);
    }
    //普通线程池非匀速运行
    public static void test3() throws InterruptedException {
        ThreadPoolExecutor pool = new ThreadPoolExecutor(2, 4, 3, TimeUnit.SECONDS, new ArrayBlockingQueue<>(20));
        pool.allowCoreThreadTimeOut(true);
        runWithVariableSpeed(pool);
    }
    //卷池非匀速运行
    public static void test4() throws InterruptedException {
        InvolutedThreadPool pool = new InvolutedThreadPool(2, 4, 3, TimeUnit.SECONDS, new ArrayBlockingQueue<>(20), 10);
        pool.allowCoreThreadTimeOut(true);
        runWithVariableSpeed(pool);
    }

    //匀速运行
    private static void runWithUniformSpeed(AbstractExecutorService pool) throws InterruptedException {
        for (int i = 0; i < 100; i++) {
            Thread.sleep(500);

            int finalI = i;
            try {
                pool.execute(new Thread() {
                    final int index = finalI;

                    @Override
                    public void run() {
                        try {
                            Thread.sleep(1900);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        System.out.println(Thread.currentThread().getName() + "--->> runWithUniformSpeed index " + index);
                    }
                });
            } catch (Exception e) {
                System.out.println(Thread.currentThread().getName() + "--->> runWithUniformSpeed fail index " + finalI);
            }
        }
    }

    //非匀速运行
    private static void runWithVariableSpeed(AbstractExecutorService pool) throws InterruptedException {
        for (int i = 0; i < 100; i++) {
            if(i % 10 < 5){
                Thread.sleep(800);
            } else {
                Thread.sleep(200);
            }

            int finalI = i;
            try {
                pool.execute(new Thread(){
                    final int index = finalI;
                    @Override
                    public void run() {
                        try {
                            Thread.sleep(1900);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        System.out.println(Thread.currentThread().getName() + "--->> runWithVariableSpeed index " + index);
                    }
                });
            } catch (Exception e) {
                System.out.println(Thread.currentThread().getName() + "--->> runWithVariableSpeed fail index " + finalI);
            }
        }
    }
}
